home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / misc / math / TCalcStats2c.lha / TCalcStats2c / AREXX / Chi-Sq_Indep.rexx < prev    next >
Encoding:
OS/2 REXX Batch file  |  1998-10-09  |  11.1 KB  |  571 lines

  1. /* Chi-Square Test for Independence rxc Contingency Table*/
  2.  
  3. options results
  4. if ~show('P','TCALC') then do
  5.     address command 'run turbocalc:turbocalc'
  6.     address command 'waitforport TCALC'
  7.     loadflag=1
  8. end
  9. address 'TCALC'
  10. 'DEFPUBSCREEN()'
  11. /* Add-in Rexx Math Library needed for some routines */
  12. signal on syntax
  13. if ~show('l','rexxmathlib.library') then
  14.    call addlib('rexxmathlib.library',0,-30) 
  15. if ~show('l','rexxreqtools.library') then
  16.    call addlib('rexxreqtools.library',0,-30)
  17. if ~show('l','rexxsupport.library') then
  18.    call addlib('rexxsupport.library',0,-30)
  19.  /* add to library list */
  20. signal off syntax
  21.  
  22. /* Start Main Routine */
  23. if loadflag=1 then 'Load()'
  24. 'ActivateWindow()'
  25. range=rtgetstring(,"Enter Cell Range for Input","Input Request") /*,,'rt_pubscrname="TCALC"')*/
  26. colon=pos(":",range)
  27. if colon=0 then do
  28.     'Message "Please select a range before executing this script"'
  29.     'DEFPUBSCREEN("Workbench")'
  30.     exit
  31. end
  32.  
  33. /* Find cell references and cell, column numbers */
  34. start_cell=substr(range,1,colon-1)
  35. end_cell=substr(range,colon+1)
  36. start_row=cellrow(start_cell)
  37. end_row=cellrow(end_cell)
  38. start_col=cellcol(start_cell)
  39. end_col=cellcol(end_cell)
  40. NRows=end_row-start_row+1
  41. NCols=end_col-start_col+1
  42.  
  43. /*Labels in First Column?*/
  44. Clabel=rtgetstring("Yes","Are there Labels in Column 1? Yes or No:","Input Request") /*,,'rt_pubscrname="TCALC"')*/
  45. Clabel=upper(left(Clabel,1))
  46. If Clabel="" then do
  47.     'DEFPUBSCREEN("Workbench")'
  48.     exit
  49. end
  50.  
  51. /* Get cell reference for output range */
  52. out_cell=rtgetstring(,"Enter Cell Reference for Output","Input Request") /*,,'rt_pubscrname="TCALC"')*/
  53. if out_cell="" then do
  54.     'DEFPUBSCREEN("Workbench")'
  55.     exit
  56. end
  57. if length(out_cell)<2 | datatype(left(out_cell,1),'n')=1 then do
  58.     'Message "Invalid cell reference"'
  59.     'DEFPUBSCREEN("Workbench")'
  60.     exit
  61. end
  62. /* Suppress Screen Redraw to Speed Things Up */
  63. 'Refresh 0'
  64.  
  65. /* Open a small output window on tcalc screen*/
  66. fo=0
  67. CR='0a'x
  68. DisplayMsg="Calculating...Please Wait."||CR||"User input is disabled during calculation."||CR
  69. if open(6Info, 'con:100/0/450/80/Progress/SCREEN TCALC', w) then do
  70.      call writeln(6Info, DisplayMsg)
  71.     fo=1
  72. end
  73. else do
  74.     'Message "TCALC Screen not available for Progress messages"'
  75. end
  76. CALL DELAY(150)
  77.  
  78. /* Get cell references for top cell in each column */
  79. top_cell.=0
  80. 'SelectCell' start_cell
  81. do col=start_col to end_col
  82.     'GetCursorPos'
  83.     top_cell.col=result
  84.     'Column 1'
  85. end
  86. if fo then call writech(6Info,"Progress...10 ")
  87. col=start_col
  88.  
  89. /* Get labels for later use on output */
  90. If Clabel="Y" then do
  91.     'SelectCell' start_cell
  92.     'CursorDown 1'
  93.     'GetValue'
  94.     do y=1 to NRows-1
  95.         'GetValue'
  96.         str=result
  97.         lefttitle.y=translate(strip(str),"_"," ")
  98.         'CursorDown 1'
  99.     end
  100. end
  101. If Clabel="Y" then do
  102.     col=start_col+1
  103.     NCols=NCols-1
  104. end
  105. say "col="col
  106. say "Clabel="Clabel
  107. 'SelectCell' top_cell.col
  108. 'GetValue'
  109. testlabel=result
  110. testlabel=strip(testlabel)
  111. if datatype(testlabel,'n')=1 then do
  112.     labelflag=0
  113.     do x=1 to NCols
  114.     title.x="Column_"||x
  115.     end
  116. end
  117. else do
  118.     labelflag=1
  119.     NRows=NRows-1
  120.     do x=1 to NCols
  121.     'GetValue'
  122.     str=result
  123.     title.x=translate(strip(str),"_"," ")
  124.     'Column 1'
  125.     end
  126. end
  127. if fo then call writech(6Info,"20 ")
  128.  
  129. /* Get data from cell range */
  130. lav=0
  131. tot=0
  132. count.=0
  133. total.=0
  134. do x=1 to NCols
  135.     'SelectCell' top_cell.col
  136.     if labelflag=1 then 'CursorDown 1'
  137.     do y=1 to NRows
  138.         'GetValue'
  139.         valtest=result
  140.         if datatype(valtest)='NUM' then do
  141.             'GetValue'
  142.             val=result
  143.             data.x.y=val
  144.             tot=tot+val
  145.             total.x=tot
  146.             count.x=1+count.x
  147.         end
  148.         'CursorDown 1'
  149.     end
  150.     col=col+1
  151.     tot=0
  152.     lav=0
  153.     val=0
  154. end
  155. if fo then call writech(6Info,"40 ")
  156. if count.1 ~= count.2 then do
  157.     'Message "Equal sample sizes required - aborting!"'
  158.     'DEFPUBSCREEN("Workbench")'
  159.     exit
  160. end
  161.  
  162. /* Sum of Row Totals */
  163. Rowtot.=0
  164. GndTot=0
  165. Do y=1 to NRows
  166.     Do x=1 to NCols
  167.         Rowtot.y=(Rowtot.y)+data.x.y
  168.     End
  169. GndTot=GndTot+Rowtot.y
  170. End
  171. if fo then call writech(6Info,"60 ")
  172.  
  173. /* Calculate Expected Frequencies */
  174.  
  175. Expect.=0
  176. Diff.=0
  177. Chi=0
  178. Do x=1 to NCols
  179.     Do y=1 to NRows
  180.         Expect.x.y=((Rowtot.y)*(total.x))/GndTot
  181.         Diff.x.y=(((data.x.y)-(Expect.x.y))**2)/Expect.x.y
  182.         Chi=Chi+Diff.x.y
  183.     end
  184. end
  185.  
  186. /* Do same with Yates Correction */
  187. ExpectY.=0
  188. DiffY.=0
  189. ChiY=0
  190. Do x=1 to NCols
  191.     Do y=1 to NRows
  192.         ExpectY.x.y=((Rowtot.y)*(total.x))/GndTot
  193.         Temp=(ABS((data.x.y)-(ExpectY.x.y)))-.5
  194.         DiffY.x.y=(Temp**2)/ExpectY.x.y
  195.         ChiY=ChiY+DiffY.x.y
  196.     end
  197. end
  198.  
  199. /* Calculations for Standardised Residuals */
  200. Res.=0
  201. Do x=1 to NCols
  202.     Do y=1 to NRows
  203.         Res.x.y=((data.x.y)-(Expect.x.y))/sqrt(Expect.x.y)
  204.     end
  205. end
  206.  
  207. /* Measures of Association */
  208.  
  209. if NCols =2 & NRows=2 then do
  210.     Phi=sqrt(Chi/GndTot) /* phi coefficient */
  211.     Q1=((data.1.1)*(data.2.2))-((data.2.1)*(data.1.2))
  212.     Q2=((data.1.1)*(data.2.2))+((data.2.1)*(data.1.2))
  213.     YuleQ=Q1/Q2 /* Yules Q coefficient */
  214.     Odd1=((data.1.1)/GndTot)*((data.1.2)/GndTot)
  215.     Odd2=((data.2.1)/GndTot)*((data.2.2)/GndTot)
  216.     OddsRatio=Odd1/Odd2 /* Odds Ratio */
  217. end
  218. PearC=sqrt(Chi/(Chi+GndTot)) /* Pearson contingency coeff */
  219. Select
  220.     when NRows <=NCols then k=NRows
  221.     when NRows>NCols then k=NCols
  222. otherwise
  223.     NOP
  224. end
  225. PhiCr=sqrt(Chi/(GndTot*(k-1))) /* Cramers Phi Coefficient */
  226.  
  227. df=(NRows-1)*(NCols-1)
  228.  
  229. /* Calculate Probability */
  230. P=CHIPROB(Chi,df)
  231. PY=CHIPROB(ChiY,df)
  232. if fo then call writech(6Info,"80 ")
  233.  
  234. /* Calculate Critical */
  235. Chicrit1=CHICRIT(.95,df)
  236. if fo then call writech(6Info,"90 ")
  237. Chicrit2=CHICRIT(.99,df)
  238.  
  239. if fo then do
  240.     call writeln(6Info,"100 ")
  241.     call writeln(6Info,"Writing output to window...")
  242. end
  243.  
  244. /* Output */
  245. 'SelectCell' out_cell
  246. 'ColumnWidth' 20
  247. 'Put "Chi Square Test for Independence"'
  248. 'CursorDown 2'
  249. 'Put "Expected Frequencies"'
  250. 'CursorDown 1'
  251. 'GetCursorPos'
  252. top_cell=result
  253. If Clabel="Y" then do
  254.     Do y=1 to NRows
  255.         'CursorDown 1'
  256.         'Put' lefttitle.y
  257.     end
  258. 'SelectCell' top_cell
  259. 'Column 1'
  260. end
  261. Do x=1 to NCols
  262.     'Alignment 2'
  263.     'Put' title.x
  264.     'CursorDown 1'
  265.     Do y=1 to NRows
  266.         'Put' Expect.x.y
  267.         'CursorDown 1'
  268.     end
  269. 'SelectCell' top_cell
  270. 'Column 2'
  271. end
  272. 'SelectCell' top_cell
  273. 'CursorDown 4'
  274. 'Put "Chi-Square:"'
  275. 'CursorDown 1'
  276. 'Put "d.f.:"'
  277. 'CursorDown 1'
  278. 'Put "P(CHI<=chi):"'
  279. 'CursorDown 1'
  280. 'Put "Chi-Critical (95%):"'
  281. 'CursorDown 1'
  282. 'Put "Chi-Critical (99%):"'
  283. 'CursorUp 4'
  284. 'Column 1'
  285. 'Put' format(Chi,,4)
  286. 'CursorDown 1'
  287. 'Put' df
  288. 'CursorDown 1'
  289. 'Put' format(P,,6)
  290. 'CursorDown 1'
  291. 'Put' format(ChiCrit1,,4)
  292. 'CursorDown 1'
  293. 'Put' format(ChiCrit2,,4)
  294. 'Column -1'
  295. 'CursorDown 1'
  296. 'Put "With Yates Correction:"'
  297. 'CursorDown 1'
  298. 'Put "Chi-Square:"'
  299. 'CursorDown 1'
  300. 'Put "P(CHI<=chi):"'
  301. 'CursorUp 1'
  302. 'Column 1'
  303. 'Put' format(ChiY,,4)
  304. 'CursorDown 1'
  305. 'Put' format(PY,,6)
  306. 'CursorDown 1'
  307. 'Column -1'
  308. 'Put "Measures of Association:"'
  309. if NCols =2 & NRows=2 then do
  310.     'CursorDown 1'
  311.     'Column 1'
  312.     'Put' format(Phi,,4)
  313.     'Column -1'
  314.     'Put "Phi Coeff.:"'
  315.     'CursorDown 1'
  316.     'Put "Yules Q:"'
  317.     'Column 1'
  318.     'Put' format(YuleQ,,4)
  319.     'CursorDown 1'
  320.     'Put' format(OddsRatio,,4)
  321.     'Column -1'
  322.     'Put "Odds Ratio:"'
  323. end
  324. 'CursorDown 1'
  325. 'Put "Pearson Cont. Coeff.:"'
  326. 'Column 1'
  327. 'Put' format(PearC,,4)
  328. 'CursorDown 1'
  329. 'Put' format(PhiCr,,4)
  330. 'Column -1'
  331. 'Put "Cramers Phi Coeff.:"'    
  332. 'Refresh 1'
  333. 'Refresh 2'
  334. /*'Message' "Finished"*/
  335. /*indicate the main script is finished*/
  336. DisplayMsg="Cleaning up ...."||CR||"Exiting"
  337. result=writeln(6Info, DisplayMsg)
  338. if result~=0 then do
  339.     /*Wait 3 seconds*/
  340.     CALL DELAY(150)
  341.     /* close window*/
  342.     result=close(6Info)
  343. end
  344. 'DEFPUBSCREEN("Workbench")'
  345. exit
  346.  
  347. /* Procedures */
  348.  
  349. cellrow: procedure
  350. do
  351.     parse arg cell
  352.     do charpos=2 to length(cell)
  353.     if datatype(substr(cell,charpos,1),n) then return substr(cell,charpos)
  354.     end
  355.     return 0
  356. end
  357. Return
  358.  
  359. cellcol: procedure
  360. do
  361.     parse arg cell
  362.     labels="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  363.     cell=upper(cell)
  364.     len=length(cell)
  365.     val=0
  366. do charpos=1 to len
  367.     if datatype(substr(cell,charpos,1),n) then
  368.     do cell=reverse(substr(cell,1,charpos-1))
  369.     do x=1 to length(cell)
  370.     val=(26**(x-1))*pos(substr(cell,x,1),labels)+val
  371.     end
  372.     return val
  373.     end
  374.     end
  375.     return 0
  376. end
  377. Return
  378. /* It is important to put the exposed array at the end of the next line */
  379. Sort: procedure expose NCols NRows data.
  380. do x=1 to NCols
  381. L=(xtoy(2,int(log(NRows-1)/log(2))))-1
  382.     Do Until L<1
  383.     L=trunc(int(L/2))
  384.     Do J=1 to L
  385.             Do K=J+L To NRows-1 By L
  386.             I=K
  387.             dumdat=data.x.I
  388.             Do while I>L
  389.                 y=I-L
  390.                 If data.x.y ~> dumdat then Leave
  391.                 data.x.I=data.x.y
  392.                 I=I-L
  393.             End
  394.             data.x.I=dumdat
  395.             End
  396.         End
  397.     End
  398. End
  399. Return
  400.  
  401. syntax:
  402.      if arg(1)='FAIL' then do
  403.         'Message "Library is unavailable."'
  404.         'DEFPUBSCREEN("Workbench")'
  405.         exit
  406.         end
  407.     'DEFPUBSCREEN("Workbench")'
  408.     exit
  409.  
  410. Format:  procedure
  411.  
  412.      arg number, before, after
  413.      CallLine = SIGL
  414.      if ~datatype(CallLine, 'N') then CallLine = '??'
  415.  
  416.      /* Make sure we have a number as first (required) argument    */
  417.      if ~datatype(number, 'N') then do
  418.         if number = '' then
  419.            fc = 17     /* Wrong number of arguments           */
  420.         else
  421.            fc = 47     /* Arithmetic conversion error             */
  422.         signal FormatSyntaxError
  423.      end
  424.      num = number + 0
  425.      if before = '' & after = '' then
  426.         return num
  427.      else do
  428.         parse var num integer '.' fraction
  429.         if before = '' then before = length(integer)
  430.         if after = '' then after = length(fraction)
  431.         if ~datatype(before, N) | ~datatype(after, N) then
  432.            do fc = 18
  433.            signal FormatSyntaxError
  434.        end
  435.         if before < length(integer) then do
  436.            fc = 18
  437.            signal FormatSyntaxError
  438.         end
  439.         if after ~= length(fraction) then do
  440.            fraction = trunc(('.'fraction'0') + ('.'copies('0', after)'5'), after)
  441.         if integer<1&integer>-1 then integer=integer
  442.            else integer = integer + (fraction % 1)
  443.            fraction = substr(fraction, 3)
  444.         end
  445.         if fraction >= 0 then
  446.            return right(integer, before)'.'fraction
  447.         else
  448.            return right(integer, before)
  449.      end
  450.  
  451.  FormatSyntaxError:
  452.         if show('F', STDERR) then
  453.            call writeln(STDERR, '+++ Error' fc 'in line' CallLine':' errortext(fc))
  454.         else
  455.            mess='+++ Error' fc 'in line' CallLine':' errortext(fc)
  456.         'Message' mess
  457.         parse source Func .
  458.         if Func = 'FUNCTION' then do
  459.         'DEFPUBSCREEN("Workbench")'
  460.            exit "Err"
  461.         end
  462.         else do
  463.         'DEFPUBSCREEN("Workbench")'
  464.            exit 10
  465.         end
  466.  
  467. CHIPROB: PROCEDURE
  468.  
  469.     PARSE ARG X2,K1
  470.     X3=0.5*X2
  471.     K3=0.5*K1
  472.     X=K3+1
  473.     LG=LOGGAMMA(X)
  474.     S=0
  475.     A=EXP(K3*LN(X3)-LG-X3)
  476.     IF A~=0 THEN DO
  477.         T=1
  478.         S=1
  479.         G=K3
  480.         DO WHILE (T/S) >.000001
  481.             G=G+1
  482.             T=T*X3/G
  483.             S=S+T
  484.         END
  485.     END
  486.     PO=S*A
  487. RETURN PO
  488.  
  489. CHICRIT: PROCEDURE
  490.  
  491.     PARSE ARG PO,K1
  492.     AO=.0001
  493.     E=.005
  494.     E2=E+E
  495.     PA=PO
  496.     SELECT
  497.     WHEN K1=1 THEN DO
  498.         PO=.5+PA/2
  499.         Z=NORMALPP(PO)
  500.         X1=Z*Z
  501.     END
  502.     WHEN K1=2 THEN DO
  503.         X1=1-PA
  504.         X1=-2*LN(X1)
  505.     END
  506.     OTHERWISE
  507.         Z=NORMALPP(PO)
  508.         A1=2/(9*K1)
  509.         W=1-A1+Z*SQRT(A1)
  510.         XO=K1*(W**3)
  511.         DO FOREVER
  512.             X2=XO
  513.             PO=CHIPROB(X2,K1)
  514.             F1=PO-PA
  515.             X2=XO+E
  516.             PO=CHIPROB(X2,K1)
  517.             F2=PO
  518.             X2=XO-E
  519.             PO=CHIPROB(X2,K1)
  520.             F2=F2-PO
  521.             F2=F2/E2
  522.             X1=XO-F1/F2
  523.             IF ABS(X1-XO)>AO THEN XO=X1
  524.             ELSE LEAVE
  525.         END    
  526.     END
  527.     X2=X1
  528. RETURN X2
  529.  
  530. LOGGAMMA: PROCEDURE
  531.  
  532.     ARG XA
  533.     C1=76.18009173
  534.     C2=-86.50532033
  535.     C3=24.01409822
  536.     C4=-1.231739516
  537.     C5=.001208580
  538.     C6=-.000005364
  539.     C7=2.506628275
  540.     X1=XA-1
  541.     W=X1+5.5
  542.     W=(X1+.5)*LN(W)-W
  543.     S=1+C1/(X1+1)+C2/(X1+2)+C3/(X1+3)
  544.     S=S+C4/(X1+4)+C5/(X1+5)+C6/(X1+6)
  545.     L=W+LN(C7*S)
  546. RETURN L
  547.  
  548. NORMALPP: PROCEDURE
  549.  
  550.     ARG P0
  551.     A1=2.515517
  552.     A2=.802853
  553.     A3=.010328
  554.     A4=1.432788
  555.     A5=.189269
  556.     A6=.001308
  557.     Q=.5-ABS(P0-.5)
  558.     SN=SIGN(-2*LN(Q))
  559.     IF SN=-1 THEN W=-1*SQRT(ABS(-2*LN(Q))
  560.     ELSE W=SQRT(-2*LN(Q))
  561.     W1=A1+W*(A2+A3*W)
  562.     W2=1+W*(A4+W*(A5+A6*W))
  563.     ZZ=W-W1/W2
  564.     SELECT
  565.         WHEN (P0-.5)<0 THEN TT=-1
  566.         WHEN (P0-.5)=0 THEN TT=0
  567.         otherwise TT=1
  568.     END
  569.     ZZ=ZZ*TT
  570. RETURN ZZ
  571.